package hooks

import (
	"encoding/base64"
	"encoding/json"
	"net"
	"os"
	"testing"

	"google.golang.org/grpc/reflection"

	"github.com/stretchr/testify/assert"
	"google.golang.org/grpc"

	pb "atomgit.com/atomgit_dev/satellite-proto/go"
)

func addPbRepositoryToEnv(repo *pb.Repository) {
	rawJson, _ := json.Marshal(repo)
	os.Setenv("AGIT_PROTO_REPOSITORY", base64.StdEncoding.EncodeToString(rawJson))
}

func GetTemporarySocketFileName() string {
	tmpfile, err := os.CreateTemp("", "satellite.socket.")
	if err != nil {
		// No point in handling this error, panic
		panic(err)
	}

	name := tmpfile.Name()
	tmpfile.Close()
	os.Remove(name)

	return name
}

func NewTestGrpcServer(streamInterceptors []grpc.StreamServerInterceptor, unaryInterceptors []grpc.UnaryServerInterceptor) *grpc.Server {
	streamInterceptors = append([]grpc.StreamServerInterceptor{}, streamInterceptors...)
	unaryInterceptors = append([]grpc.UnaryServerInterceptor{}, unaryInterceptors...)
	return grpc.NewServer(
		grpc.ChainStreamInterceptor(streamInterceptors...),
		grpc.ChainUnaryInterceptor(unaryInterceptors...),
	)
}

func startTestServices(t *testing.T) (*grpc.Server, string) {
	server := NewTestGrpcServer(nil, nil)
	serverSocketPath := "localhost:58089"

	listener, err := net.Listen("tcp4", serverSocketPath)
	if err != nil {
		t.Fatal("failed to start server")
	}

	pb.RegisterHookServiceServer(server, NewHookServer())
	reflection.Register(server)

	go func() {
		assert.NoError(t, server.Serve(listener), "server serve GPRC failed")
	}()

	// It will return tcp4 protocol for grpc
	return server, "tcp4://" + serverSocketPath
}

type mockServer struct {
	pb.UnimplementedHookServiceServer
}

func NewHookServer() pb.HookServiceServer {
	return &mockServer{}
}
